﻿/*========================== 
 * @author 郑金泉
 * @desc SQL 复合条件类
 * ========================= */
using System;
using System.Collections.Generic;
using System.Text;

namespace Obsidian.Data.Sql
{
    public class CompoundCondition : SqlCondition, ISqlCondition
    {

        private List<ISqlCondition> subConditions = new List<ISqlCondition>();

        public List<ISqlCondition> SubConditions
        {
            get { return this.subConditions; }
        }

        public CompoundCondition AddSubCondition(ISqlCondition sqlCondition)
        {
            if (this.subConditions.Count > 0 &&
                this.subConditions[0].LogicalOperator != Sql.LogicalOperator.AND &&
                sqlCondition.LogicalOperator == Sql.LogicalOperator.AND)
            {
                subConditions.Insert(0, sqlCondition);
            }
            else
            {
                subConditions.Add(sqlCondition);
            }
            return this;
        }

        public CompoundCondition And(ISqlCondition sqlCondition)
        {
            sqlCondition.LogicalOperator = Sql.LogicalOperator.AND;
            return this.AddSubCondition(sqlCondition);
        }

        public CompoundCondition Or(ISqlCondition sqlCondition)
        {
            sqlCondition.LogicalOperator = Sql.LogicalOperator.OR;
            return this.AddSubCondition(sqlCondition);
        }

        public CompoundCondition Not(ISqlCondition sqlCondition)
        {
            sqlCondition.LogicalOperator = Sql.LogicalOperator.NOT;
            return this.AddSubCondition(sqlCondition);
        }

        public string BuildSqlText()
        {
            StringBuilder sb = new StringBuilder();
            if (this.subConditions.Count > 0)
            {
                if (this.subConditions.Count == 1)
                {
                    sb.Append(this.subConditions[0].BuildSqlText());
                }
                else
                {
                    sb.Append("(");
                    bool first = true;
                    foreach (ISqlCondition condition in this.subConditions)
                    {
                        if (first)
                            first = false;
                        else
                            sb.Append(" ").Append(condition.GetLogicalOperatorString()).Append(" ");
                        sb.Append(condition.BuildSqlText());
                    }
                    sb.Append(")");
                }
            }
            return sb.ToString();
        }

    }
}
